/*
*	Project: Aethon
*
*	File: Control.h
*
*	Author: Jonathan Hersack
*
*	Date: 2/15/2009
*
*   Purpose: The Control handles the keyboard/mouse input for the 
*   user-to-model interaction
*/

#ifndef CONTROL_H_
#define CONTROL_H_

#include <iostream>
#include <GL/glut.h>
#include "../include/Model.h"
#include "../include/ModelPart.h"
#include "../include/vector3f.h"
#include "../include/Quaternion.h"
#include <GL/glut.h>
#include <math.h>

using namespace std;

 
class Control{

    bool isActive;//if Director::handlernumber refers to this handler, used to check if registered or not.  
	Model* modelPtr;
	int* handlerNumberPtr;//used to tell director which handler to register
	
	
	Quaternion yRotation;//heading
	Quaternion xRotation;//pitch
	vector3f diffVel;
	//const float PixelDegreeFactor = 0.2;

	//vector3f diffDir;//change in direction, caused by mouse motion
	int lastX;// initial center values
	int lastY; 
	int CenterX;// initial center values
	int CenterY; 
	int DeadZone;
	int InvertedLook;//should be 1 to invert vertical look -1 for non-inverted
	int InvertedHorizLook;
	float m_MaxPitchRate;
	float m_MaxHeadingRate;
	float m_MaxForwardVelocity;
	float m_ForwardVelocity;
	float m_RightVelocity;
	
	protected:
	Control()
	{
	CenterX = 320;
	CenterY = 240; 
	DeadZone = 1;
	InvertedLook = -1;
	InvertedHorizLook = -1;
	lastX = CenterX;// initial center values
	lastY = CenterY;
	m_MaxPitchRate=5.0f;
	m_MaxHeadingRate = 5.0f;
	m_MaxForwardVelocity=5.0f;
	m_ForwardVelocity = 0.0f;
	m_RightVelocity = 0.0f;
	}
	Control(const Control&);//protect operations so instances are limited
	Control& operator = (const Control&);//protect operations so instances are limited

	
	private:
	static Control* pinstance;
	
	public:
	static Control* getInstanceOf();//returns instance of Control
	static void keyboardHandle(unsigned char key, int x, int y);
    static void specialHandle(int key, int x, int y);
	static void mouseHandle(int x, int y);
	
	void updateVelocity();
	void updateDirection();
	void changeHeading(float degrees);
	void changePitch(float degrees);
	void changeRightVelocity(float vel);
	void changeForwardVelocity(float vel);
	void stopVelocity();
	vector3f calcPoints(vector3f angles);
	vector3f normalizeVector(vector3f vect);
	vector3f crossProduct(vector3f vectf, vector3f vetu);
	//gets and sets-----------------------------------------------------------
   	
	void setIsActive(bool active)
	{
         isActive = active;
    }//end setiswire
    
	bool getIsActive()
	{
         return isActive;
    }//end getisactive
    
	void setModelPtr(Model* ptr)
	{
         modelPtr = ptr;
    }//end setiswire
    
	void setHandleNumberPtr(int* ptr)
	{
        handlerNumberPtr = ptr;
    }//end setHandlePtr
	
	int* getHandleNumberPtr()
	{
        return handlerNumberPtr;
    }//end setHandlePtr
    
	Model* getModelPtr()
	{
         return modelPtr;
    }//end getisactive

	void setDiffVel(vector3f vel)
	{
         diffVel = vel;
    }//end setDiffVel
    
	vector3f getDiffVel()
	{
         return diffVel;
    }//end getdiffVel
	
	void toggleInversion()
	{
		InvertedLook = InvertedLook * -1;
	}//end
	
	void toggleHorizInversion()
	{
		InvertedHorizLook = InvertedHorizLook * -1;
	}//end
	
	void setSize(int width, int height)
	{
			CenterX = width/2;
			CenterY = height/2; 
			lastX = CenterX;// initial center values
			lastY = CenterY;
	}//end setSize
	
};//end class

#endif //CONTROL_H_

